import { ChangeEvent, useState } from 'react';
import { Input, InputProps, Progress } from 'antd';
import './index.less';

export enum StrengthLevelEnum {
  None = 0,
  TooWeak = 20,
  Weak = 40,
  Medium = 60,
  Strong = 80,
  VeryStrong = 100,
}

interface IProps extends InputProps {
  strength?: number;
  checkStrength?: boolean;
  onChangeStrength?: (value: number) => void;
}

const AntdPassword = Input.Password;

export default function Password(props: IProps) {
  const {
    checkStrength,
    onChangeStrength,
    strength: baseStrength,
    value,
    onChange: onChangeValue,
    ...restProps
  } = props;
  const [strength, setStrength] = useState<number>(baseStrength ?? StrengthLevelEnum.None);
  const getPasswordStrength = (value: string) => {
    let strengthLevel = 0;
    let type: StrengthLevelEnum = StrengthLevelEnum.None;
    // 检查密码长度
    if (value.length >= 8) strengthLevel += 1;
    // 检查是否包含数字
    if (/\d/.test(value)) strengthLevel += 1;
    // 检查是否包含大小写字母
    if (/[a-z]/.test(value)) strengthLevel += 1;
    if (/[A-Z]/.test(value)) strengthLevel += 1;
    // 检查是否包含特殊字符
    if (/[^a-zA-Z0-9]/.test(value)) strengthLevel += 1;
    switch (strengthLevel) {
      case 1:
        type = StrengthLevelEnum.TooWeak;
        break;
      case 2:
        type = StrengthLevelEnum.Weak;
        break;
      case 3:
        type = StrengthLevelEnum.Medium;
        break;
      case 4:
        type = StrengthLevelEnum.Strong;
        break;
      case 5:
        type = StrengthLevelEnum.VeryStrong;
    }
    setStrength(type);
    onChangeStrength && onChangeStrength(type);
  };
  const onChange = (e: ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    getPasswordStrength(value);
    onChangeValue && onChangeValue(e);
  };

  return (
    <>
      <AntdPassword value={value} onChange={onChange} {...restProps} />
      {checkStrength && (
        <div className="flex justify-start items-center">
          <Progress percent={strength} steps={5} showInfo={false} className="mt-[5px] password" />
        </div>
      )}
    </>
  );
}
